"""
用户视图和API
"""
from rest_framework import viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from django.contrib.auth import get_user_model, authenticate
from rest_framework.authtoken.models import Token
from .models import UserFollow, EmailVerification, PhoneVerification
from .serializers import UserSerializer, UserRegisterSerializer, UserFollowSerializer
from utils.image_utils import validate_image, compress_image
from utils.email_utils import send_verification_email
from django.utils.crypto import get_random_string
from django.utils import timezone
from django.conf import settings
from datetime import timedelta
from django.core.cache import cache

User = get_user_model()


class UserViewSet(viewsets.ModelViewSet):
    """用户视图集"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    
    def get_queryset(self):
        """优化查询"""
        queryset = super().get_queryset()
        # 使用select_related优化外键查询
        queryset = queryset.select_related()
        return queryset
    
    def get_permissions(self):
        """
        根据不同的action返回不同的权限类
        """
        if self.action in ['register', 'login']:
            return [permissions.AllowAny()]
        return super().get_permissions()
    
    @action(detail=False, methods=['post'])
    def register(self, request):
        """用户注册"""
        try:
            serializer = UserRegisterSerializer(data=request.data)
            if serializer.is_valid():
                user = serializer.save()
                # 注册成功后不自动登录，只返回成功消息和用户基本信息
                return Response({
                    'message': '注册成功，请登录',
                    'user': {
                        'id': user.id,
                        'username': user.username,
                        'email': user.email
                    }
                }, status=status.HTTP_201_CREATED)
            return Response({
                'error': '注册失败',
                'details': serializer.errors
            }, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({
                'error': f'注册失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=False, methods=['post'])
    def login(self, request):
        """用户登录"""
        try:
            username = request.data.get('username')
            password = request.data.get('password')
            
            if not username or not password:
                return Response({'error': '用户名和密码不能为空'}, status=status.HTTP_400_BAD_REQUEST)
            
            user = authenticate(username=username, password=password)
            if user:
                if not user.is_active:
                    return Response({'error': '账户已被禁用'}, status=status.HTTP_403_FORBIDDEN)
                token, created = Token.objects.get_or_create(user=user)
                return Response({
                    'token': token.key,
                    'user': UserSerializer(user).data
                })
            return Response({'error': '用户名或密码错误'}, status=status.HTTP_401_UNAUTHORIZED)
        except Exception as e:
            return Response({
                'error': f'登录失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=True, methods=['get', 'put'])
    def preferences(self, request, pk=None):
        """获取/更新用户偏好（更新后清理推荐缓存）"""
        user = self.get_object()
        if request.method == 'PUT':
            user.preferences = request.data.get('preferences', {})
            user.save()
            # 清理与用户相关的推荐缓存
            try:
                from django.core.cache import cache
                # 删除内容推荐缓存
                try:
                    cache.delete_pattern(f'content_based_rec_{user.id}_*')
                except Exception:
                    pass
                # 删除综合推荐缓存
                try:
                    cache.delete_pattern(f'attraction_recommendations_{user.id}_*')
                except Exception:
                    pass
            except Exception:
                pass
        return Response({'preferences': user.preferences})
    
    @action(detail=True, methods=['get'])
    def posts(self, request, pk=None):
        """获取用户的动态列表（分页）"""
        user = self.get_object()
        from apps.social.models import Post
        from apps.social.serializers import PostSerializer
        
        # 使用select_related和prefetch_related优化查询
        posts_qs = Post.objects.filter(user=user).select_related(
            'user', 'route_plan'
        ).prefetch_related(
            'post_images', 'comments', 'likes'
        ).order_by('-created_at')
        
        # 分页返回
        from rest_framework.pagination import PageNumberPagination
        paginator = PageNumberPagination()
        try:
            page_size = int(request.query_params.get('page_size', 20))
        except Exception:
            page_size = 20
        paginator.page_size = page_size
        page = paginator.paginate_queryset(posts_qs, request, view=self)
        serializer = PostSerializer(page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)
    
    @action(detail=True, methods=['get'])
    def favorites(self, request, pk=None):
        """获取用户的收藏列表（景点和路线）"""
        user = self.get_object()
        from apps.attractions.models import AttractionFavorite
        from apps.routes.models import RouteFavorite
        
        # 获取景点收藏
        attraction_favorites = AttractionFavorite.objects.filter(user=user).select_related(
            'attraction'
        ).order_by('-created_at')
        
        # 获取路线收藏
        route_favorites = RouteFavorite.objects.filter(user=user).select_related(
            'route_plan', 'route_plan__start_attraction'
        ).order_by('-created_at')
        
        return Response({
            'attractions': [
                {
                    'id': fav.id,
                    'attraction': {
                        'id': fav.attraction.id,
                        'name': fav.attraction.name,
                        'category': fav.attraction.category,
                        'ticket_price': str(fav.attraction.ticket_price),
                        'rating': fav.attraction.rating,
                        'address': fav.attraction.address,
                        'primary_image': fav.attraction.amap_image_urls[0] if fav.attraction.amap_image_urls else None
                    },
                    'created_at': fav.created_at
                }
                for fav in attraction_favorites
            ],
            'routes': [
                {
                    'id': fav.id,
                    'route_plan': {
                        'id': fav.route_plan.id,
                        'start_attraction': {
                            'id': fav.route_plan.start_attraction.id,
                            'name': fav.route_plan.start_attraction.name
                        },
                        'budget': str(fav.route_plan.budget),
                        'total_cost': str(fav.route_plan.total_cost),
                        'total_distance': fav.route_plan.total_distance,
                        'created_at': fav.route_plan.created_at
                    },
                    'created_at': fav.created_at
                }
                for fav in route_favorites
            ]
        })
    
    @action(detail=True, methods=['get'])
    def profile(self, request, pk=None):
        """获取用户主页信息（包含统计信息）"""
        user = self.get_object()
        from apps.social.models import Post
        from apps.attractions.models import AttractionFavorite
        from apps.routes.models import RouteFavorite
        from apps.itineraries.models import Itinerary
        
        # 统计信息
        posts_count = Post.objects.filter(user=user).count()
        attractions_favorites_count = AttractionFavorite.objects.filter(user=user).count()
        routes_favorites_count = RouteFavorite.objects.filter(user=user).count()
        itineraries_count = Itinerary.objects.filter(user=user).count()
        
        serializer = self.get_serializer(user)
        data = serializer.data
        data['stats'] = {
            'posts_count': posts_count,
            'attractions_favorites_count': attractions_favorites_count,
            'routes_favorites_count': routes_favorites_count,
            'itineraries_count': itineraries_count,
            'total_favorites_count': attractions_favorites_count + routes_favorites_count
        }
        
        return Response(data)
    
    @action(detail=True, methods=['post'])
    def change_password(self, request, pk=None):
        """修改密码"""
        user = self.get_object()
        current_user = request.user
        
        # 只能修改自己的密码
        if user != current_user:
            return Response(
                {'error': '只能修改自己的密码'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        old_password = request.data.get('old_password')
        new_password = request.data.get('new_password')
        new_password_confirm = request.data.get('new_password_confirm')
        
        if not old_password or not new_password or not new_password_confirm:
            return Response(
                {'error': '请填写完整信息'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 验证旧密码
        if not user.check_password(old_password):
            return Response(
                {'error': '原密码错误'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 验证新密码
        if new_password != new_password_confirm:
            return Response(
                {'error': '两次新密码输入不一致'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        if len(new_password) < 6:
            return Response(
                {'error': '新密码长度不能少于6个字符'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 设置新密码
        user.set_password(new_password)
        user.save()
        
        return Response({
            'message': '密码修改成功，请重新登录'
        }, status=status.HTTP_200_OK)
    
    @action(detail=True, methods=['post', 'delete'])
    def follow(self, request, pk=None):
        """关注/取消关注用户（节流保护）"""
        # 节流：针对关注操作进行用户级限流
        try:
            from rest_framework.throttling import UserRateThrottle
            throttle = UserRateThrottle()
            throttle.allow_request(request, self)  # 如果超额将由DRF处理
        except Exception:
            pass
        target_user = self.get_object()
        current_user = request.user
        
        if request.method == 'POST':
            if current_user == target_user:
                return Response({'error': '不能关注自己'}, status=status.HTTP_400_BAD_REQUEST)
            follow, created = UserFollow.objects.get_or_create(
                follower=current_user,
                following=target_user
            )
            if created:
                return Response({'message': '关注成功'}, status=status.HTTP_201_CREATED)
            return Response({'message': '已关注'}, status=status.HTTP_200_OK)
        elif request.method == 'DELETE':
            UserFollow.objects.filter(
                follower=current_user,
                following=target_user
            ).delete()
            return Response({'message': '取消关注成功'}, status=status.HTTP_200_OK)
    
    @action(detail=False, methods=['get'])
    def me(self, request):
        """获取当前用户信息"""
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)
    
    @action(detail=False, methods=['post'], permission_classes=[permissions.IsAuthenticated])
    def upload_avatar(self, request):
        """上传用户头像"""
        if 'avatar' not in request.FILES:
            return Response(
                {'error': '请选择要上传的头像'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        avatar_file = request.FILES['avatar']
        
        # 验证图片
        is_valid, error_message = validate_image(avatar_file)
        if not is_valid:
            return Response(
                {'error': error_message},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # 压缩图片
            compressed_avatar = compress_image(avatar_file, max_size=(400, 400), quality=90)
            
            # 更新用户头像
            request.user.avatar = compressed_avatar
            request.user.save()
            
            serializer = self.get_serializer(request.user)
            return Response({
                'message': '头像上传成功',
                'user': serializer.data
            }, status=status.HTTP_200_OK)
            
        except Exception as e:
            return Response(
                {'error': f'头像上传失败：{str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'], permission_classes=[permissions.IsAuthenticated])
    def send_email_verification(self, request):
        """发送邮箱验证码"""
        email = request.data.get('email')
        if not email:
            return Response(
                {'error': '请提供邮箱地址'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 验证邮箱格式
        from django.core.validators import validate_email
        from django.core.exceptions import ValidationError
        try:
            validate_email(email)
        except ValidationError:
            return Response(
                {'error': '邮箱格式不正确'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 检查是否在1分钟内已发送过验证码（防止频繁发送）
        cache_key = f'email_verification_sent_{request.user.id}_{email}'
        if cache.get(cache_key):
            return Response(
                {'error': '验证码已发送，请稍后再试'},
                status=status.HTTP_429_TOO_MANY_REQUESTS
            )
        
        # 生成6位数字验证码
        verification_code = get_random_string(length=6, allowed_chars='0123456789')
        
        # 创建验证记录
        verification = EmailVerification.objects.create(
            user=request.user,
            email=email,
            verification_code=verification_code
        )
        
        # 发送验证邮件
        if send_verification_email(request.user, email, verification_code):
            # 设置缓存，1分钟内不能重复发送
            cache.set(cache_key, True, 60)
            return Response({
                'message': '验证码已发送到您的邮箱，请查收',
                'expires_at': verification.expires_at.isoformat()
            }, status=status.HTTP_200_OK)
        else:
            verification.delete()
            return Response(
                {'error': '邮件发送失败，请稍后重试'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'], permission_classes=[permissions.IsAuthenticated])
    def verify_email(self, request):
        """验证邮箱"""
        email = request.data.get('email')
        verification_code = request.data.get('verification_code')
        
        if not email or not verification_code:
            return Response(
                {'error': '请提供邮箱地址和验证码'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 查找验证记录
        try:
            verification = EmailVerification.objects.filter(
                user=request.user,
                email=email,
                verification_code=verification_code,
                is_verified=False
            ).order_by('-created_at').first()
            
            if not verification:
                return Response(
                    {'error': '验证码错误或已使用'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 检查是否过期
            if verification.is_expired():
                return Response(
                    {'error': '验证码已过期，请重新获取'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 验证成功
            verification.is_verified = True
            verification.save()
            
            # 更新用户邮箱和验证状态
            request.user.email = email
            request.user.email_verified = True
            request.user.save()
            
            return Response({
                'message': '邮箱验证成功',
                'email': email
            }, status=status.HTTP_200_OK)
            
        except Exception as e:
            return Response(
                {'error': f'验证失败：{str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'], permission_classes=[permissions.IsAuthenticated])
    def send_phone_verification(self, request):
        """发送手机验证码（需要短信服务商，这里仅提供接口框架）"""
        phone = request.data.get('phone')
        if not phone:
            return Response(
                {'error': '请提供手机号'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 验证手机号格式（简单验证）
        if not phone.isdigit() or len(phone) != 11:
            return Response(
                {'error': '手机号格式不正确'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 检查是否在1分钟内已发送过验证码
        cache_key = f'phone_verification_sent_{request.user.id}_{phone}'
        if cache.get(cache_key):
            return Response(
                {'error': '验证码已发送，请稍后再试'},
                status=status.HTTP_429_TOO_MANY_REQUESTS
            )
        
        # 生成6位数字验证码
        verification_code = get_random_string(length=6, allowed_chars='0123456789')
        
        # 创建验证记录
        verification = PhoneVerification.objects.create(
            user=request.user,
            phone=phone,
            verification_code=verification_code
        )
        
        # TODO: 这里需要集成短信服务商API（如阿里云、腾讯云等）
        # 目前仅返回验证码（开发环境），生产环境需要调用短信API
        if settings.DEBUG:
            # 开发环境：返回验证码（仅用于测试）
            return Response({
                'message': '验证码已发送（开发环境）',
                'verification_code': verification_code,  # 仅开发环境返回
                'expires_at': verification.expires_at.isoformat()
            }, status=status.HTTP_200_OK)
        else:
            # 生产环境：需要调用短信API
            # 这里可以集成阿里云、腾讯云等短信服务
            return Response(
                {'error': '短信服务未配置'},
                status=status.HTTP_503_SERVICE_UNAVAILABLE
            )
    
    @action(detail=False, methods=['post'], permission_classes=[permissions.IsAuthenticated])
    def verify_phone(self, request):
        """验证手机号"""
        phone = request.data.get('phone')
        verification_code = request.data.get('verification_code')
        
        if not phone or not verification_code:
            return Response(
                {'error': '请提供手机号和验证码'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 查找验证记录
        try:
            verification = PhoneVerification.objects.filter(
                user=request.user,
                phone=phone,
                verification_code=verification_code,
                is_verified=False
            ).order_by('-created_at').first()
            
            if not verification:
                return Response(
                    {'error': '验证码错误或已使用'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 检查是否过期
            if verification.is_expired():
                return Response(
                    {'error': '验证码已过期，请重新获取'},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # 验证成功
            verification.is_verified = True
            verification.save()
            
            # 更新用户手机号和验证状态
            request.user.phone = phone
            request.user.phone_verified = True
            request.user.save()
            
            return Response({
                'message': '手机号验证成功',
                'phone': phone
            }, status=status.HTTP_200_OK)
            
        except Exception as e:
            return Response(
                {'error': f'验证失败：{str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
